package com.geoai.uimap.core.amap

import com.amap.api.maps.model.Arc
import com.amap.api.maps.model.ArcOptions
import com.geoai.basiclib.utils.log.MyLogUtils
import com.geoai.uimap.api.IGEOMap
import com.geoai.uimap.api.GEOMapArc
import com.geoai.uimap.geo.Point
import com.geoai.uimap.geo.SimpleProjection
import com.geoai.uimap.model.GEOLatLng
import com.geoai.uimap.utils.MathUtils
import com.geoai.uimap.utils.SphericalUtil
import com.geoai.uimap.utils.dpToPx
import com.geoai.uimap.utils.getAMap

class GDMapArc(private val map: IGEOMap) : GEOMapArc() {
    private var mArc: Arc? = null
    override fun show(): GEOMapArc {
        if (mArcInfo == null) return this
        mArc = map.getAMap()?.addArc(getMidPoint())
        return this
    }

    private fun getMidPoint():ArcOptions{
        val startPoint = IGEOMap.getGeoLatlng(map, mArcInfo!!.start)
        var endPoint = IGEOMap.getGeoLatlng(map,mArcInfo!!.end)
        val simpleProjection = SimpleProjection(startPoint) //基点
        val mArcAngle = mArcInfo!!.mAngel
        val mClockwise = mArcInfo!!.mClockwise
        val midAngle = if (mClockwise) (mArcInfo!!.startAngle- mArcAngle / 2) else (mArcInfo!!.startAngle + mArcAngle / 2)
        val mid = MathUtils.getPointOnCircle(mArcInfo!!.circle, Math.toRadians(midAngle.toDouble()))
        val midPoint = simpleProjection.Point2GeoPoint(Point(mid.x, mid.y))
        val midP =  IGEOMap.getGdLatlng(map, GEOLatLng(midPoint.latitude, midPoint.longitude))
        val endAngle = if (mClockwise) (mArcInfo!!.startAngle- mArcAngle ) else (mArcInfo!!.startAngle + mArcAngle )
        val end = MathUtils.getPointOnCircle(mArcInfo!!.circle, Math.toRadians(endAngle.toDouble()))
        endPoint = simpleProjection.Point2GeoPoint(Point(end.x, end.y))

        val endP = IGEOMap.getGdLatlng(map, endPoint)
        val startP = IGEOMap.getGdLatlng(map, startPoint)
        val arcOptions = ArcOptions()
        arcOptions.point(startP, midP, endP)
        arcOptions.strokeColor(mLineColor).strokeWidth(dpToPx(mWidth))
        return arcOptions
    }

    /**
     * 如果没有传入中间点，则计算中间点
     */
    private fun getMidPointV2(): ArcOptions {
        val startPoint = IGEOMap.getGeoLatlng(map, mArcInfo!!.start)
        val endPoint = IGEOMap.getGeoLatlng(map,mArcInfo!!.end)
        val mArcAngle = mArcInfo!!.mAngel
        val mClockwise = mArcInfo!!.mClockwise
        val simpleProjection = SimpleProjection(startPoint) //基点
        val sPoint = simpleProjection.GeoPoint2Point(startPoint)
        val ePoint = simpleProjection.GeoPoint2Point(endPoint)
        val centerPoint = Point((sPoint.x + ePoint.x) / 2, (sPoint.y + ePoint.y) / 2)
        val circle: MathUtils.Circle = MathUtils.Circle()
        circle.center.x = centerPoint.x
        circle.center.y = centerPoint.y
        circle.radius = SphericalUtil.computeDistanceBetween(startPoint, endPoint) / 2

        var startAngle = Math.atan2((sPoint.y - centerPoint.y), (sPoint.x - centerPoint.x))
        startAngle = 180 * startAngle / Math.PI//转换为角度值
        if (startAngle < 0)
            startAngle += 360

        MyLogUtils.d("start===$startAngle")
        val newAngle = if (mClockwise) (startAngle - mArcAngle / 2) else (startAngle + mArcAngle / 2)

        val mid = MathUtils.getPointOnCircle(circle, Math.toRadians(newAngle))
        val midPoint = simpleProjection.Point2GeoPoint(Point(mid.x, mid.y))
        val midP = IGEOMap.getGdLatlng(map, GEOLatLng(midPoint.latitude, midPoint.longitude))
        var endP = IGEOMap.getGdLatlng(map, endPoint)
        if (mArcAngle != 180f) {
            val endAngle = if (mClockwise) (startAngle - mArcAngle) else (startAngle + mArcAngle)
            val end = MathUtils.getPointOnCircle(circle, Math.toRadians(endAngle))
            val newEndPoint = simpleProjection.Point2GeoPoint(Point(end.x, end.y))
            endP = IGEOMap.getGdLatlng(map, GEOLatLng(newEndPoint.latitude, newEndPoint.longitude))
        }
        val startP = IGEOMap.getGdLatlng(map, startPoint)
        val arcOptions = ArcOptions()
        arcOptions.point(startP, midP, endP)
        arcOptions.strokeColor(mLineColor).strokeWidth(dpToPx(mWidth))
        return arcOptions

    }

    override fun destroy() {
        mArc?.remove()
    }
}